# Tutorial

## blink with LED

This is platform-neural tutorial, although hardware implementation refers to
arduino. The full code can be found at `examples/atmega328p/blink-led.cpp`

Let's start from the inclusion of headers:

```
#include <rotor-light.hpp>
```

All further interactions with the framework is done via `rl` namespace

```
namespace rl = rotor_light;
```

In this example, there is only single message - `BlinkCommand`. It is good
practice to define messages in it's own namespace, as it is much more
convenient to deail with messages later (handle and send).

```
namespace message {

struct BlinkCommand : rl::Message {
  static constexpr auto type_id = __LINE__;
  using rl::Message::Message;
  rl::MessageTypeId get_type_id() const override { return type_id; }
};

} // namespace message
```

The `BlinkCommand` message have to be derived from `rotor_ligth` `Message`,
and as the `BlinkCommand` has no payload, it just reuses its parent
consturctor (`using rl::Message::Message`).

As the `rotor_ligth` does not uses RTTI it should somehow identify
message types at runtime. That's why overriden `get_type_id()` method
should be available on every message type. `rotor_light` does not care
how you, as the user, define your message type, the only requirement is the
uniqueness of them. The easiest way to achieve that is just have line

```
  static constexpr auto type_id = __LINE__;
```

in every message type definition, and group all used messages in a single
header file.

Let's move to the blinker actor code; as it is rather small, it is shown
entirely:

```
struct Blinker : rl::Actor<2> {
using Parent = Actor<2>;

void initialize() override {
  subscribe(&Blinker::on_blink_command);
  Parent::initialize();
}

void advance_start() override {
  Parent::advance_start();
  add_event(
      delay, [](void *data) { static_cast<Blinker *>(data)->blink(); }, this);
}

void blink() {
  toggle_led();
  add_event(
      delay, [](void *data) { static_cast<Blinker *>(data)->blink(); }, this);
}

void on_blink_command(message::BlinkCommand &msg) { blink(); }

rl::Duration delay;
};
```
